added Feb 2001 SDK
[windows-sources.git] / shared source / sscli20 / jscript / engine / regexpliteral.cs
blobe96cc402471d395d81ef4e9f0463b05d57938705
1 // ==++==
2 //
3 //
4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
5 //
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
10 //
11 // You must not remove this notice, or any other, from this software.
12 //
13 //
14 // ==--==
16 namespace Microsoft.JScript {
18 using Microsoft.JScript.Vsa;
19 using System;
20 using System.Reflection;
21 using System.Reflection.Emit;
22 using System.Globalization;
24 internal sealed class RegExpLiteral : AST {
25 private String source;
26 private bool ignoreCase, global, multiline;
27 private JSGlobalField regExpVar;
29 private static int counter = 0;
32 internal RegExpLiteral(String source, String flags, Context context)
33 : base(context) {
34 this.source = source;
35 this.ignoreCase = this.global = this.multiline = false;
36 if (flags != null)
37 for (int i = 0; i < flags.Length; i++)
38 switch (flags[i]) {
39 case 'i':
40 if (this.ignoreCase)
41 throw new JScriptException(JSError.RegExpSyntax);
42 this.ignoreCase = true;
43 break;
44 case 'g':
45 if (this.global)
46 throw new JScriptException(JSError.RegExpSyntax);
47 this.global = true;
48 break;
49 case 'm':
50 if (this.multiline)
51 throw new JScriptException(JSError.RegExpSyntax);
52 this.multiline = true;
53 break;
54 default:
55 throw new JScriptException(JSError.RegExpSyntax);
59 internal override Object Evaluate() {
60 if( VsaEngine.executeForJSEE )
61 throw new JScriptException(JSError.NonSupportedInDebugger);
62 RegExpObject regExpObject = (RegExpObject)Globals.RegExpTable[this];
63 if (regExpObject == null) {
64 regExpObject = (RegExpObject)this.Engine.GetOriginalRegExpConstructor().Construct
65 (this.source, this.ignoreCase, this.global, this.multiline);
66 Globals.RegExpTable[this] = regExpObject;
68 return regExpObject;
71 internal override IReflect InferType(JSField inferenceTarget){
72 return Typeob.RegExpObject;
75 internal override AST PartiallyEvaluate() {
76 String id = "regexp "+(RegExpLiteral.counter++).ToString(CultureInfo.InvariantCulture);
77 GlobalScope gs = (GlobalScope)this.Engine.GetGlobalScope().GetObject();
78 JSGlobalField v = (JSGlobalField)gs.AddNewField(id, null, FieldAttributes.Assembly);
79 v.type = new TypeExpression(new ConstantWrapper(Typeob.RegExpObject, this.context));
80 this.regExpVar = v;
81 return this;
84 internal override void TranslateToIL(ILGenerator il, Type rtype) {
85 il.Emit(OpCodes.Ldsfld, (FieldInfo)this.regExpVar.GetMetaData());
86 Convert.Emit(this, il, Typeob.RegExpObject, rtype);
89 internal override void TranslateToILInitializer(ILGenerator il) {
90 ScriptObject scope = this.Engine.ScriptObjectStackTop();
91 while (scope != null && (scope is WithObject || scope is BlockScope))
92 scope = scope.GetParent();
93 if (scope is FunctionScope){
94 this.EmitILToLoadEngine(il); //Make sure engine gets initialized every time function is entered
95 il.Emit(OpCodes.Pop);
97 il.Emit(OpCodes.Ldsfld, (FieldInfo)this.regExpVar.GetMetaData());
98 Label exit = il.DefineLabel();
99 il.Emit(OpCodes.Brtrue_S, exit);
100 this.EmitILToLoadEngine(il);
101 il.Emit(OpCodes.Call, CompilerGlobals.getOriginalRegExpConstructorMethod);
102 il.Emit(OpCodes.Ldstr, this.source);
103 if (this.ignoreCase)
104 il.Emit(OpCodes.Ldc_I4_1);
105 else
106 il.Emit(OpCodes.Ldc_I4_0);
107 if (this.global)
108 il.Emit(OpCodes.Ldc_I4_1);
109 else
110 il.Emit(OpCodes.Ldc_I4_0);
111 if (this.multiline)
112 il.Emit(OpCodes.Ldc_I4_1);
113 else
114 il.Emit(OpCodes.Ldc_I4_0);
115 il.Emit(OpCodes.Call, CompilerGlobals.regExpConstructMethod);
116 il.Emit(OpCodes.Castclass, Typeob.RegExpObject);
117 il.Emit(OpCodes.Stsfld, (FieldInfo)this.regExpVar.GetMetaData());
118 il.MarkLabel(exit);